#include <iostream>

using std::cout;
using std::endl;

class Base
{
public:
    Base(long base = 0)
    : _base(base)
    {
        cout << "Base(long = 0)" << endl;
    }

    virtual
    void func()
    {
        cout << "void Base::func()" << endl;
    }

    virtual
    void gunc()
    {
        cout << "void Base::gunc()" << endl;
    }

    virtual
    void hunc()
    {
        cout << "void Base::hunc()" << endl;
    }

    ~Base()
    {
        cout << "~Base()" << endl;
    }
private:
    long _base;
};

class Derived
: public Base
{
public:
    Derived(long base = 0, long derived = 0)
    : Base(base)
    , _derived(derived)
    {
        cout << "Derived(long = 0, long  = 0)" << endl;
    }

    virtual
    void func()
    {
        cout << "void Derived::func()" << endl;
    }

    virtual
    void gunc()
    {
        cout << "void Derived::gunc()" << endl;
    }

    virtual
    void hunc()
    {
        cout << "void Derived::hunc()" << endl;
    }

    ~Derived()
    {
        cout << "~Derived()" << endl;
    }
private:
    long _derived;
};

void test2()
{

}
void test()
{
    //虚表是存在的，存在与只读段
    //对于普通的单继承而言，虚表只有一张
    //
    Derived derived(100, 200);
    printf("对象derived的地址: %p\n", &derived);
    printf("对象derived的地址: %p\n", (long *)&derived);
    printf("虚表的地址: %p\n", (long *)*(long *)&derived);
    printf("第一个虚函数的地址: %p\n", 
           (long *)*(long *)*(long *)&derived);

    /* typedef int A; */
    /* typedef void (*pFunc)(void); */
    /* pFunc c = test2; */

    typedef void (*pFunc)(void);
    pFunc f = (pFunc)* ((long*)*(long *)&derived);
    printf("第一个虚函数的地址 : %p\n", f);
    f();//第一个虚函数的调用

    cout << endl;
                                  //1代表的是一个基本单位
    pFunc g = (pFunc)* ((long *)*(long *)&derived + 1);
    printf("第二个虚函数的地址 : %p\n", g);
    g();//第二个虚函数的调用

    cout << endl;
    pFunc h = (pFunc)* ((long *)*(long *)&derived + 2);
    printf("第三个虚函数的地址 : %p\n", h);
    h();//第三个虚函数的调用

    cout << endl << endl << endl;
    Derived derived2(111, 222);
    printf("对象derived2的地址: %p\n", &derived2);
    printf("对象derived2的地址: %p\n", (long *)&derived2);
    printf("虚表的地址: %p\n", (long *)*(long *)&derived2);
    printf("第一个虚函数的地址: %p\n", 
           (long *)*(long *)*(long *)&derived2);

    cout << "_base = " << (long )*((long *)&derived + 1) << endl;
    cout << "_derived = " << (long )*((long *)&derived + 2) << endl;
}

int main(int argc, char **argv)
{
    test();
    return 0;
}

